package com.ruoyi.system.service.impl;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.async.ResultCallback;
import com.github.dockerjava.api.async.ResultCallbackTemplate;
import com.github.dockerjava.api.command.ExecCreateCmdResponse;
import com.github.dockerjava.api.command.InspectContainerResponse;
import com.github.dockerjava.api.model.*;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.core.RemoteApiVersion;
import com.github.dockerjava.core.SSLConfig;
import com.github.dockerjava.okhttp.OkDockerHttpClient;
import com.ruoyi.system.entity.SunPanelDockerList;
import com.ruoyi.system.entity.SunPanelDockerListItem;
import com.ruoyi.system.entity.SunPanelDockerListItemPorts;
import com.ruoyi.system.entity.SunPanelDockerStatus;
import com.ruoyi.system.service.IDockerService;
import com.ruoyi.system.service.ISysConfigService;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;

import java.io.Closeable;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DockerServiceImpl implements IDockerService {
    @Resource
    private ISysConfigService sysConfigService;

    //获取容器状态
    @Override
    public HashMap<String, SunPanelDockerStatus> getContainersStats(List<String> ids) throws Exception {
        HashMap<String, SunPanelDockerStatus> stringSunPanelDockerStatusHashMap = new HashMap<>();

        for (String id : ids) {
            try {
                DockerClient connect = connect();

                InspectContainerResponse exec = connect.inspectContainerCmd(id).exec();
                final Statistics[] statistics = {null};

                connect.statsCmd(id).withNoStream(true).exec(new ResultCallback<Statistics>() {
                            @Override
                            public void onStart(Closeable closeable) {

                            }

                            @Override
                            public void onNext(Statistics object) {
                                statistics[0] =object;
                            }

                            @Override
                            public void onError(Throwable throwable) {

                            }

                            @Override
                            public void onComplete() {

                            }

                            @Override
                            public void close() throws IOException {

                            }
                        });
                int time = 1;
                while (statistics[0]==null&&time<3){
                    Thread.sleep(1000);
                    time++;
                }

                SunPanelDockerStatus value = new SunPanelDockerStatus();

                if (statistics[0]!=null) {
                    try {
                        CpuUsageConfig cpuUsage = statistics[0].getCpuStats().getCpuUsage();
                        value.setCpuPercent((double) cpuUsage.getUsageInUsermode()/cpuUsage.getTotalUsage());
                        MemoryStatsConfig memoryStats = statistics[0].getMemoryStats();
                        value.setMemory((double) memoryStats.getUsage()/1024/1024);
                    }catch (Exception e){}
                }
                value.setCache(0);
                value.setIoRead(0);
                value.setIoWrite(0);
                value.setNetworkRX(0);
                value.setNetworkTX(0);
                value.setRunStatus(exec.getState().getStatus());
                value.setErrorMessage("");
                value.setShotTime(new Date());

                stringSunPanelDockerStatusHashMap.put(id, value);
            }catch (Exception e){
                System.out.println(e);
            }

        }

        //{
        //    "code": 0,
        //    "data": {
        //        "cpuPercent": 0.0005282620179609086,
        //        "memory": 27.1484375,
        //        "cache": 0,
        //        "ioRead": 1.80859375,
        //        "ioWrite": 0,
        //        "networkRX": 388282.419921875,
        //        "networkTX": 388790.2998046875,
        //        "runStatus": "running",
        //        "errorMessage": "",
        //        "shotTime": "2025-06-20T13:36:51.966019527Z"
        //    },
        //    "msg": "OK"
        //}

        return stringSunPanelDockerStatusHashMap;
    }

    //启动或停止容器
    @Override
    public void execSwitchActionByContainerID(boolean action, String id) throws Exception {
        DockerClient connect = connect();
        if (action) {
            connect.startContainerCmd(id).exec();
        }else {
            connect.stopContainerCmd(id).exec();
        }
    }

    //获取 容器列表
    @Override
    public SunPanelDockerList getList() throws Exception {
        SunPanelDockerList sunPanelDockerList = new SunPanelDockerList();


        //Docker
        List<Container> exec = connect().listContainersCmd().withShowAll(true).exec();
        ArrayList<SunPanelDockerListItem> list = new ArrayList<>();
        for (Container container : exec) {
            SunPanelDockerListItem e = new SunPanelDockerListItem();
            e.setId(container.getId());
            e.setImage(container.getImage());
            e.setName("docker-run-"+container.getNames()[0].replace("/",""));
            e.setState(container.getState());
            e.setStatus(container.getStatus());
            e.setCreateTime(new Date(container.getCreated()).toString().replace("T"," ").split("/.")[0]);

            if (e.getPorts()!=null) {
                ArrayList<SunPanelDockerListItemPorts> ports = new ArrayList<>();
                for (SunPanelDockerListItemPorts port : e.getPorts()) {
                    SunPanelDockerListItemPorts e1 = new SunPanelDockerListItemPorts();
                    e1.setIp(port.getIp());
                    e1.setType(port.getType());
                    e1.setPrivatePort(port.getPrivatePort());
                    e1.setPublicPort(port.getPublicPort());
                    ports.add(e1);
                }
                e.setPorts(ports);
            }



            list.add(e);
        }

        sunPanelDockerList.setList(list);
        sunPanelDockerList.setCount(list.size());
        return sunPanelDockerList;
    }

    public void exec() throws Exception{
        DockerClient connect = connect();

    }





    //连接到docker
    private DockerClient connect() throws Exception{
        String host = sysConfigService.selectConfigByKey("docker.host");
        OkDockerHttpClient build = new OkDockerHttpClient.Builder().dockerHost(new URI(host)).build();
        DockerClient dockerClient = DockerClientImpl.getInstance(new DockerClientConfig() {
            @Override
            public URI getDockerHost() {
                try {
                    return new URI(host);
                } catch (URISyntaxException e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public RemoteApiVersion getApiVersion() {
                return RemoteApiVersion.UNKNOWN_VERSION ;
            }

            @Override
            public String getRegistryUsername() {
                return null;
            }

            @Override
            public String getRegistryPassword() {
                return null;
            }

            @Override
            public String getRegistryEmail() {
                return null;
            }

            @Override
            public String getRegistryUrl() {
                return null;
            }

            @Override
            public AuthConfig effectiveAuthConfig(String imageName) {
                return null;
            }

            @Override
            public AuthConfigurations getAuthConfigurations() {
                return null;
            }

            @Override
            public SSLConfig getSSLConfig() {
                return null;
            }
        },build);
        return dockerClient;
    }
}
